package com.neusoft.SPNursingHome.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.neusoft.SPNursingHome.dao.BedDao;
import com.neusoft.SPNursingHome.dao.BedRecordDao;
import com.neusoft.SPNursingHome.dao.ClientDao;
import com.neusoft.SPNursingHome.po.Bed;
import com.neusoft.SPNursingHome.po.BedRecord;
import com.neusoft.SPNursingHome.po.Client;
import com.neusoft.SPNursingHome.po.ResponseBean;
import com.neusoft.SPNursingHome.po.*;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.stream.Collectors;
import java.util.*;

@Service
public class BedServiceImpl implements BedService {

    @Resource
    private BedRecordDao bedRecordDao;
    @Resource
    private ClientDao clientDao;
    @Resource
    private BedDao bedDao;
    @Override
    public ResponseBean<Void> update(Bed bed) {
        int rows = bedDao.updateById(bed);
        if (rows != 1) {
            return new ResponseBean<>(500, "MealSet 更新失败");
        }
        return new ResponseBean<>();
    }

    @Override
    public ResponseBean<List<String>> getAllFloors() {
        try {
            QueryWrapper<Bed> wrapper = new QueryWrapper<>();
            wrapper.select("DISTINCT floor_id").orderByAsc("floor_id");
            List<String> floors = bedDao.selectObjs(wrapper).stream()
                    .map(Object::toString)
                    .collect(Collectors.toList());
            return new ResponseBean<>(floors);
        } catch (Exception e) { return new ResponseBean<>(500, "获取楼层列表失败"); }
    }

    @Override
    public ResponseBean<Map<String, List<Bed>>> findAvailableBedsByFloor(String floorId) {
        try {
            QueryWrapper<Bed> wrapper = new QueryWrapper<>();
            wrapper.eq("floor_id", floorId).eq("bed_status", "空闲");
            List<Bed> beds = bedDao.selectList(wrapper);
            Map<String, List<Bed>> groupedBeds = beds.stream().collect(Collectors.groupingBy(Bed::getRoomId));
            return new ResponseBean<>(groupedBeds);
        } catch (Exception e) { return new ResponseBean<>(500, "获取可用床位失败"); }
    }

    @Override
    public ResponseBean<Map<String, Object>> getBedChartByFloor(String floorId) {
        try {
            // 1. 查询指定楼层的所有床位
            QueryWrapper<Bed> wrapper = new QueryWrapper<>();
            wrapper.eq("floor_id", floorId);
            List<Bed> bedsOnFloor = bedDao.selectList(wrapper);

            // 2. 计算统计数据
            long total = bedsOnFloor.size();
            long vacant = bedsOnFloor.stream().filter(b -> "空闲".equals(b.getBedStatus())).count();
            long occupied = bedsOnFloor.stream().filter(b -> "有人".equals(b.getBedStatus())).count();
            long out = bedsOnFloor.stream().filter(b -> "外出".equals(b.getBedStatus())).count();

            Map<String, Long> statistics = new HashMap<>();
            statistics.put("total", total);
            statistics.put("vacant", vacant);
            statistics.put("occupied", occupied);
            statistics.put("out", out);

            // 3. 按房间号分组，形成房间布局
            Map<String, List<Bed>> roomLayout = bedsOnFloor.stream()
                    .collect(Collectors.groupingBy(Bed::getRoomId));

            // 4. 组合最终结果
            Map<String, Object> result = new HashMap<>();
            result.put("statistics", statistics);
            result.put("layout", roomLayout);

            return new ResponseBean<>(result);

        } catch (Exception e) {
            return new ResponseBean<>(500, "获取床位图表数据失败: " + e.getMessage());
        }
    }

    @Override
    public boolean updateBedUsageEndTime(Integer bedRecordId, Date endTime) {
        BedRecord record = new BedRecord();
        record.setBedRecordId(bedRecordId);
        record.setBedEndTime(endTime);
        record.setBedRecordStatus(0); // 状态改为“使用历史”
        return bedRecordDao.updateById(record) > 0;
    }
    @Override
    @Transactional // *** 确保所有数据库操作的原子性，要么全部成功，要么全部失败 ***
    public boolean swapBedForClient(Integer clientId, Integer newBedId) {
        // 步骤 1: 验证新床位是否可用
        Bed newBed = bedDao.selectById(newBedId);
        if (newBed == null || !"空闲".equals(newBed.getBedStatus())) {
            throw new RuntimeException("调换失败：目标床位不存在或不是空闲状态！");
        }

        // 步骤 2: 找到客户当前正在使用的床位记录 (status=1)
        QueryWrapper<BedRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("client_id", clientId).eq("bed_record_status", 1);
        BedRecord oldBedRecord = bedRecordDao.selectOne(queryWrapper);

        if (oldBedRecord == null) {
            throw new RuntimeException("调换失败：未找到客户当前正在使用的床位记录！");
        }
        Integer oldBedId = oldBedRecord.getBedId();

        // 步骤 3: 将旧床位使用记录标记为失效，并设置结束时间为当前 (对应您的第一点要求)
        oldBedRecord.setBedRecordStatus(0); // 状态改为0 (使用历史)
        oldBedRecord.setBedEndTime(new Date()); // 结束时间为当前日期
        bedRecordDao.updateById(oldBedRecord);

        // 步骤 4: 添加新床位的使用记录，入住时间为当前日期 (对应您的第三点要求)
        BedRecord newBedRecord = new BedRecord();
        newBedRecord.setClientId(clientId);
        newBedRecord.setBedId(newBedId);
        newBedRecord.setBedBeginTime(new Date()); // 入住时间为当前日期
        newBedRecord.setBedRecordStatus(1); // 状态为“正在使用”
        bedRecordDao.insert(newBedRecord);

        // 步骤 5: 修改旧床位的状态为空闲，新床位的状态为有人 (对应您的第四点要求)
        Bed oldBedToUpdate = new Bed();
        oldBedToUpdate.setBedId(oldBedId);
        oldBedToUpdate.setBedStatus("空闲");
        bedDao.updateById(oldBedToUpdate);

        Bed newBedToUpdate = new Bed();
        newBedToUpdate.setBedId(newBedId);
        newBedToUpdate.setBedStatus("有人");
        bedDao.updateById(newBedToUpdate);

        // 步骤 6: 更新客户信息 (对应您的第五点要求)
        // **重要说明**: 根据您的表结构, `client` 表只存储了 `bed_id`。
        // 客户的房间号、楼号等信息是通过 `bed_id` 关联到 `bed` 表来获取的。
        // 因此，我们只需要更新 `client` 表中的 `bed_id` 字段，该客户的房间号、楼号等信息就自动跟着更新了。
        Client clientToUpdate = new Client();
        clientToUpdate.setClientId(clientId);
        clientToUpdate.setBedId(newBedId); // 只需更新 bed_id 即可
        clientDao.updateById(clientToUpdate);

        return true;
    }
    @Override
    public ResponseBean<List<String>> listRoomsWithFreeBeds() {
        List<String> rooms = bedDao.selectRoomsWithFreeBeds();
        return new ResponseBean<>(rooms);
    }

    @Override
    public ResponseBean<List<Bed>> listFreeBedsByRoom(String roomId) {
        List<Bed> beds = bedDao.selectFreeBedsByRoom(roomId);
        return new ResponseBean<>(beds);
    }


}